package com.huan.order.config;

import com.huan.config.DefaultConfiguration;
import feign.Logger;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * spring-cloud-starter-loadbalancer 底层源码流程：
 * spring-cloud-starter-loadbalancer 提供一个负载均衡工厂 LoadBalancerClientFactory （继承 NamedContextFactory） 用来构建负载均衡客服端
 *   1. LoadBalancerClientFactory 有个默认配属性类 LoadBalancerClientConfiguration，这个类是每个 远程服务 公共配置！每个 远程服务都有自己独属自己的一份配置，这个配置就是 LoadBalancerClientConfiguration
 *      每个远程服务配置它是怎么确保配置隔离的？它在远程调用服务时候，如你使用 openfegin 调用远程服务时候，它会在进行负载均衡之前 调用 loadBalancerClientFactory.getInstances(...)方法 传递你的远程服务名称。
 *      重要的远程服务隔离配置就是在 getInstance 方法里面（此时是进到 LoadBalancerClientFactory 类里面）！ 在方法内部它会 根据 你传递的服务名 创建一个 spring ioc 容器！
 *      该ioc容器它的配置bean 就是来自于在创建 LoadBalancerClientFactory 类时候指定的 LoadBalancerClientConfiguration 数据配置类；最后把 该ioc 容器添加到 LoadBalancerClientFactory 的 contexts Map里面
 *      最后进行负载均衡 BlockingLoadBalancerClient.choose() 方法进行负载均衡。
 *   2. BlockingLoadBalancerClient.choose()
 *     来的 choose()方法，它会调用 LoadBalancerClientFactory 类 getInstance 方法，根据你的远程服务名称获取一个 loadBalancerClientFactory.getInstance(serviceId) 一个负载均衡器类 ReactiveLoadBalancer。
 *     注：ReactiveLoadBalancer 这个类就是从上一步的 子容器 创建的
 *
 *   3. ReactiveLoadBalancer（实现类 RoundRobinLoadBalancer） 默认实现是轮询
 *      ReactiveLoadBalancer里面 属性 有一个 ClientFactoryObjectProvider 该作用就是提供一个 ServiceInstanceListSupplier  服务实例对象 ，该对象作用就是去 nacos 获取服务实例 ，最后调用远程服务
 *      注意： ServiceInstanceListSupplier 这个对象不是真正对外暴露的，它进行了委托，委托在 DelegatingServiceInstanceListSupplier 类 ，所以真正对外暴露的是 DelegatingServiceInstanceListSupplier（实现类 CachingServiceInstanceListSupplier）
 *     在创建的时候 CachingServiceInstanceListSupplier 类时候，此时就去连接 nacos 服务 获取当前的的服务实例，流程:采用响应式编程方式。
 *
 *
 *  4. 重要对象流程已经关系梳理好了，接下来是梳理调用流程：
 *     当我们使用 openFegin 调用远程服务。会根据服务名称从 LoadBalancerClientFactory对象  contexts Map 属性获取 spring ioc子容器获取一个负载均衡器对象 RoundRobinLoadBalancer（默认轮询）
 *     然后获取一个 ServiceInstanceListSupplier 服务实例对 真正对外提供的是 DelegatingServiceInstanceListSupplier 类，此时也知道 在创建 DelegatingServiceInstanceListSupplier的时候，它就通过 真正的 ServiceInstanceListSupplier
 *     去获取 nacos 上获取当前服务所以服务实例对象，最终采用取模的方式得到最终要调用的服务实例对象。
 *
 */
@Configuration
@EnableFeignClients(basePackages = "com.huan.api")
public class FeignConfig {

}
